package com.shiehub.sdk.opengw.encrypt;


import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.lang.RandomStringUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * @Description: RSA非对称型加密的公钥和私钥
 * @Author: guoleijie@shie.com.cn
 * @Since:2016-9-12
 */
public class DESedeUtil {

  /**
   * 主密钥
   */
  private static final String MAIN_SECRET_KEY = "aaaaaaaaaaaaaaaaaaaashie";

  /**
   * 用于随机数生成
   */
  private static final String RANDOM_STRING = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

  /**
   * 采用默认的主密钥进行加密
   *
   * @param str 需要加密的字符串
   * @return 返回3DES加密后的串
   */
  public static final String encrypt(final String str) {
    return encrypt(MAIN_SECRET_KEY, str);
  }

  /**
   * 进行3DES加密
   *
   * @param key 加密KEY
   * @param str 需要加密的字符串
   * @return 返回3DES加密后的串
   */
  public static final String encrypt(final String key, final String str) {
    String result = null;
    try {
      // 获取密钥
      SecretKey secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "DESede");
      Cipher enCipher = Cipher.getInstance("DESede");
      // Cipher.ENCRYPT_MODE：加密
      enCipher.init(Cipher.ENCRYPT_MODE, secretKey);
      byte[] encrypt = enCipher.doFinal(str.getBytes());
      BASE64Encoder b64e = new BASE64Encoder();
      result = b64e.encode(encrypt);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    return result;
  }

  /**
   * 采用默认的主密钥进行解密
   *
   * @param str 需要解密的字符串
   * @return 返回3DES解密后的串
   */
  public static final String decrypt(final String str) {
    return decrypt(MAIN_SECRET_KEY, str);
  }

  /**
   * 进行3DES解密
   *
   * @param key 解密KEY
   * @param str 需要解密的字符串
   * @return 返回3DES解密后的串
   */
  public static final String decrypt(String key, final String str) {
    String result = null;
    try {
      // 获取密钥
      SecretKey secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "DESede");
      Cipher deCipher = Cipher.getInstance("DESede");
      // Cipher.DECRYPT_MODE：解密
      deCipher.init(Cipher.DECRYPT_MODE, secretKey);
      byte[] decrypt = deCipher.doFinal(new BASE64Decoder().decodeBuffer(str));
      result = new String(decrypt);
    } catch (Exception ex) {

    }
    return result;
  }

  /**
   * @Description: 私钥加签
   * @param: strPrivateKey 加签私钥
   * @param: strPlainVal 待加签字符串
   * @ReturnType: String
   * @exception:
   * @Author: guoleijie@shie.com.cn
   * @Since: 创建时间 2016年12月12日 下午2:20:47
   */
  public static String privateKeySign(String strPrivateKey, String strPlainVal) {
    try {
      String md5SignStr = MD5Util.md5(strPlainVal);
      String desSignStr = DESedeUtil.encrypt(strPrivateKey, md5SignStr);
      return desSignStr;
    } catch (Exception e) {

    }
    return null;
  }

  /**
   * @Description: 私钥验签
   * @param: strPrivateKey 验签私钥
   * @param: strSignVal加签值
   * @param: strVerifyVal 待加签字符串
   * @ReturnType: boolean
   * @exception:
   * @Author: guoleijie@shie.com.cn
   * @Since: 创建时间 2016年12月12日 下午2:29:53
   */
  public static boolean privateKeyVerify(String strPrivateKey, String strSignVal,
      String strVerifyVal) {
    try {
      String md5VerifyStr = MD5Util.md5(strVerifyVal);
      String desVerifyStr = DESedeUtil.encrypt(strPrivateKey, md5VerifyStr);
      boolean verifyResult = desVerifyStr.equals(strSignVal);//验签
      return verifyResult;
    } catch (Exception e) {

    }
    return false;
  }


  /**
   * 生成与统一前置登录报文交互时的密码
   */
  public static final String getSesionPassword() {
    String randomStr = randomString();
    return encrypt(randomStr);
  }

  /**
   * 生成[0-9][a-z][A-Z]的随机串
   */
  public static final String randomString() {
    return RandomStringUtils.random(24, RANDOM_STRING);
  }

  public static void main(String[] args) {
    String randomStr = randomString();
    System.err.println("加密前明文：" + randomStr);
    String encrypt = encrypt(MAIN_SECRET_KEY, randomStr);
    String plain = decrypt(MAIN_SECRET_KEY, encrypt);
    System.err.println("解密后明文:" + plain);
    //加签
    String signStr = privateKeySign(MAIN_SECRET_KEY, randomStr);
    //验签
    boolean verifyResult = privateKeyVerify(MAIN_SECRET_KEY, signStr, randomStr);
    System.err.println("验签结果：" + verifyResult);
  }
}
